#!/usr/bin/env python
# encoding: utf-8
"""
@Author: Beam
@Mail:506556658@qq.com
@file: sqlalchemy基础.py
@time: 2017/6/15 10:34
"""

# 创建方式
# MySQL-Python
# mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
# pymysql
# mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
# MySQL-Connector
# mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname>
# cx_Oracle
# oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...]



import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base  #orm基类方法
from sqlalchemy import Column, Integer, String, ForeignKey   #导入字段方法
from sqlalchemy.orm import sessionmaker  #从orm中导入方法

engine = create_engine("mysql+pymysql://Beam:liang123456@192.168.6.248/beam?charset=utf8",encoding='utf-8', echo=False)  #创建引擎,使用什么样的方式操作mysql  ,参数echo表示会打印执行的信息

Base = declarative_base()  # 生成orm基类，用import的方法生成基类


class User(Base): #一个表一个类
    __tablename__ = 'user'  #创建一个表的写法
    id = Column(Integer,autoincrement=True,primary_key=True) #id这个字段为主键
    name = Column(String(32))
    password = Column(String(64))

    def __repr__(self):
        #这样可以直接实例对象直接打算返回的数据，而不是打印一个内存地址
        return "<User(name='%s',  password='%s')>" % (
            self.name, self.password)

Base.metadata.create_all(engine)  #注意要把engine填进去，通过base这个实例对象调用metadata.create_all方法创建表结构


#用orm创建一个对象
Session_class = sessionmaker(bind=engine)  # 创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例
Session = Session_class()  # 生成session实例
# #通过orm对象执行操作，如插入：
# user_obj = User(name="Mity", password="chen123456")  # 生成你要创建的数据对象，User是之前创建表的雷鸣
# print(user_obj.name, user_obj.id)  # 此时还没创建对象呢，不信你打印一下id发现还是None
# Session.add(user_obj)  # 把要创建的数据对象添加到这个session里， 一会统一创建
# print(user_obj.name, user_obj.id)  # 此时也依然还没创建
# Session.commit()  # 现此才统一提交，创建数据

# #查询
# select_user = Session.query(User).filter_by(name='Mity').first() #first()只获取第一条记录，filter_by等于sql里的where
# print(select_user)  #>>:如果定义表的类没有__repr__方法,那么<__main__.User object at 0x000001C4AC4BD208>   这样只输出一个内存地址
# print(select_user.id,select_user.name,select_user.password) #>>:1 Beam liang123456
# print(Session.query(User.id,User.name,User.password).all() )   #打印user表所有信息


# #修改
# print(Session.query(User.id,User.name,User.password).all() )
# update_user = Session.query(User).filter_by(name="Beam").first() #first()是默认第一条的，切记
# update_user.name = "Bob"
# Session.commit()
# print(Session.query(User.id,User.name,User.password).all() )

# #回滚
# select_user = Session.query(User).filter_by(name='Bob').first()
# print(select_user)  #因为User表已经用了__repr__方法，所以可以直接打印具体数据内容，而不是内存地址
# fake_user = User(name='Rain', password='12345')
# Session.add(fake_user)
# print(Session.query(User).filter(User.name.in_(['Jack','rain'])).all() )  #这时看session里有你刚添加和修改的数据
# Session.rollback() #此时你rollback一下,这里是重点，所以不需要像普通的mysql执行事务需要begin
# print(Session.query(User).filter(User.name.in_(['Jack','rain'])).all() ) #再查就发现刚才添加的数据没有了。
# # Session.commit()

# #获取所有数据
# print(Session.query(User.name,User.id).all() )  #获取所有数据

# #多条件查询
# objs = Session.query(User).filter(User.id>0).filter(User.name=='Mity').all()  #多条件查询，注意用的是filter不是fileter_by
# print(objs)


# #统计和分组
# count = Session.query(User).filter(User.name.like("Mi%")).count()  #匹配User表的name字段含有Mi的数据，并count起来
# print(count)
# from sqlalchemy import func
# print(Session.query(func.count(User.name),User.name).group_by(User.name).all() ) #统计整个表，name字段相同的个数
# '''相当于sql:SELECT count(user.name) AS count_1, user.name AS user_name FROM user GROUP BY user.name'''










































